package com.doujiao.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.doujiao.auth.mapper.AdminMapper;
import com.doujiao.auth.service.AdminGroupPermissionService;
import com.doujiao.auth.service.AdminGroupService;
import com.doujiao.auth.service.AdminService;
import com.doujiao.auth.utils.JwtUtil;
import com.doujiao.core.auth.dto.LoginDTO;
import com.doujiao.core.auth.entity.Admin;
import com.doujiao.core.auth.vo.LoginVO;
import com.doujiao.core.exceptions.BusinessException;
import com.doujiao.core.exceptions.enums.RespEnum;
import com.doujiao.core.Result;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.doujiao.core.auth.dto.AdminQueryDTO;
import com.doujiao.core.auth.vo.AdminPageVO;
import com.doujiao.core.auth.entity.AdminGroupPermission;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class AdminServiceImpl implements AdminService {


    @Resource
    private final AdminMapper adminMapper;
    @Resource
    private final PasswordEncoder passwordEncoder;
    @Resource
    private final JwtUtil jwtUtil;
    @Resource
    private final AdminGroupService adminGroupService;
    @Resource
    private final AdminGroupPermissionService adminGroupPermissionService;


    @Override
    public List<String> getAdminPermissions(Long adminId) {
        // 1. 查询管理员信息
        Admin admin = adminMapper.selectById(adminId);
        if (admin == null) {
            throw new BusinessException(RespEnum.INVALID_ACCOUNT);
        }

        // 2. 如果是超级管理员，返回所有权限
        if (admin.getIsSuper()==1) {
            return adminGroupPermissionService.list().stream()
                    .map(AdminGroupPermission::getPermission)
                    .distinct()
                    .collect(Collectors.toList());
        }

        // 3. 查询组权限
        return adminGroupPermissionService.getPermissionsByGroupId(admin.getGroupId());
    }

    @Override
    public LoginVO login(LoginDTO loginDTO) {

        // 1. 根据用户名查询管理员
        Admin admin = adminMapper.selectOne(
                new LambdaQueryWrapper<Admin>()
                        .eq(Admin::getName, loginDTO.getUsername())
        );

        // 2. 验证用户是否存在
        if (admin == null) {
            throw new BusinessException(RespEnum.INVALID_ACCOUNT);
        }

        log.info("password: {}", passwordEncoder.encode(loginDTO.getPassword()));

        // 3. 验证密码是否正确
        if (!passwordEncoder.matches(loginDTO.getPassword(), admin.getPassword())) {
            throw new BusinessException(RespEnum.INVALID_ACCOUNT);
        }

        // 4. 生成JWT Token
        HashMap<String, Object> map = new HashMap<>();
        map.put("adminId", admin.getAdminId());

        String accessToken = jwtUtil.generateAccessToken(map);
        String refreshToken = jwtUtil.generateRefreshToken();

        // 5. 返回登录结果
        return LoginVO.builder()
                .accessToken(accessToken)
                .refreshToken(refreshToken)
                .adminId(admin.getAdminId())
                .name(admin.getName())
                .avatar(admin.getAvatar())
                .build();
    }

    @Override
    public Long createAdmin(Admin admin) {
        // 检查用户名是否已存在
        Long count = adminMapper.selectCount(
                new LambdaQueryWrapper<Admin>()
                        .eq(Admin::getName, admin.getName())
        );
        if (count > 0) {
            throw new BusinessException(RespEnum.USERNAME_EXISTS);
        }

        // 加密密码
        admin.setPassword(passwordEncoder.encode(admin.getPassword()));
        // 默认不禁用
        admin.setDisabled(false);

        adminMapper.insert(admin);
        return admin.getAdminId();
    }

    @Override
    public Boolean updateAdmin(Admin admin) {
        // 验证管理员存在
        Admin existingAdmin = adminMapper.selectById(admin.getAdminId());
        if (existingAdmin == null) {
            throw new BusinessException(RespEnum.INVALID_ACCOUNT);
        }

        // 不更新密码，除非明确提供了新密码
        if (admin.getPassword() == null || admin.getPassword().isEmpty()) {
            admin.setPassword(existingAdmin.getPassword());
        } else {
            admin.setPassword(passwordEncoder.encode(admin.getPassword()));
        }

        return adminMapper.updateById(admin) > 0;
    }

    @Override
    public Boolean updateAdminStatus(Long adminId, Boolean disabled) {
        Admin admin = new Admin();
        admin.setAdminId(adminId);
        admin.setDisabled(disabled);
        return adminMapper.updateById(admin) > 0;
    }

    @Override
    public AdminPageVO<Admin> queryAdmins(AdminQueryDTO queryDTO) {
        // 构建分页参数
        Integer page = queryDTO.getPage() != null ? queryDTO.getPage() : 1;
        Integer size = queryDTO.getSize() != null ? queryDTO.getSize() : 10;
        Page<Admin> pageParam = new Page<>(page, size);
        
        // 构建查询条件
        LambdaQueryWrapper<Admin> queryWrapper = new LambdaQueryWrapper<>();
        if (queryDTO.getId() != null) {
            queryWrapper.eq(Admin::getAdminId, queryDTO.getId());
        }
        if (queryDTO.getUsername() != null && !queryDTO.getUsername().isEmpty()) {
            queryWrapper.like(Admin::getName, queryDTO.getUsername());
        }
        if (queryDTO.getGroupId() != null) {
            queryWrapper.eq(Admin::getGroupId, queryDTO.getGroupId());
        }
        if (queryDTO.getDisabled() != null) {
            queryWrapper.eq(Admin::getDisabled, queryDTO.getDisabled());
        }

        // 执行分页查询
        IPage<Admin> result = adminMapper.selectPage(pageParam, queryWrapper);

        // 构建返回结果
        AdminPageVO<Admin> pageVO = new AdminPageVO<>();
        pageVO.setTotal(result.getTotal());
        pageVO.setRecords(result.getRecords());
        return pageVO;
    }
}
